package com.winsdom.service.customer.impl;

import com.winsdom.entity.customer.CustomerPersonalBasicInfoRequest;
import com.winsdom.mapper.customer.CustomerPersonalBasicInfoMapper;
import com.winsdom.service.customer.CustomerPersonalBasicInfoService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 个人客户基本信息服务实现类
 * <p>
 * 负责处理个人客户基本信息的查询业务逻辑，包括：
 * 1. 从数据库查询个人客户基础信息（主表数据）
 * 2. 组装客户基本信息与联系人及其关联的楼盘信息
 * 3. 处理查询结果中的空值和关联数据分组
 * </p>
 * <p>
 * 依赖{@link CustomerPersonalBasicInfoMapper}完成数据库操作，
 * 返回封装了客户信息和联系人信息的{@link CustomerPersonalBasicInfoRequest}对象。
 * </p>
 */
@Service
public class CustomerPersonalBasicInfoServiceImpl implements CustomerPersonalBasicInfoService {

    @Resource
    private CustomerPersonalBasicInfoMapper customerPersonalBasicInfoMapper;

    /**
     * 根据客户ID查询个人客户基本信息（含联系人及关联楼盘信息）
     * <p>
     * 业务逻辑：
     * 1. 调用Mapper执行查询，结果可能包含多行数据（主信息+联系人+楼盘关联的多表联查结果）
     * 2. 若查询结果为空，返回空的基本信息对象（联系人列表为空）
     * 3. 从首条记录中提取客户主信息（如姓名、手机号、证件信息等）
     * 4. 按联系人ID分组，收集所有联系人信息及对应的楼盘名称
     * 5. 将分组后的联系人信息封装到结果对象中返回
     * </p>
     *
     * @param customerId 个人客户ID
     * @return {@link CustomerPersonalBasicInfoRequest}对象，包含：
     *         <ul>
     *             <li>客户基本信息（customerId、姓名、手机号等）</li>
     *             <li>联系人列表（每个联系人包含姓名、电话及关联的楼盘名称）</li>
     *         </ul>
     *         若未找到客户记录，返回的对象中联系人列表为空。
     */
    @Override
    public CustomerPersonalBasicInfoRequest getCustomerPersonalBasicInfo(Long customerId) {
        // 调用Mapper查询数据库，获取原始数据（可能包含主信息和联系人关联信息的多表结果）
        List<Map<String, Object>> resultList = customerPersonalBasicInfoMapper.selectCustomerPersonalBasicInfo(customerId);
        // 初始化返回的客户基本信息对象
        CustomerPersonalBasicInfoRequest basicInfo = new CustomerPersonalBasicInfoRequest();

        // 处理查询结果为空的情况（客户不存在或无数据）
        if (resultList.isEmpty()) {
            // 设置空的联系人列表，避免返回null
            basicInfo.setContactInfos(Collections.emptyList());
            return basicInfo;
        }

        // ====================== 1. 提取客户主表基本信息 ======================
        // 主信息存在于首条记录（多表联查时主信息会重复出现在每条记录中，取第一条即可）
        Map<String, Object> baseInfo = resultList.get(0);
        // 填充客户基本信息字段（直接映射数据库表字段）
        basicInfo.setCustomerId(customerId);
        basicInfo.setCustomerType((Integer) baseInfo.get("customer_type"));        // 客户类型（1:个人）
        basicInfo.setCustomerName((String) baseInfo.get("customer_name"));        // 客户姓名
        basicInfo.setMobilePhone((String) baseInfo.get("mobile_phone"));          // 手机号码
        basicInfo.setIdType((String) baseInfo.get("id_type"));                    // 证件类型（如身份证、护照等）
        basicInfo.setIdNumber((String) baseInfo.get("id_number"));                // 证件号码
        basicInfo.setEmail((String) baseInfo.get("email"));                        // 电子邮箱
        basicInfo.setIdImagePath((String) baseInfo.get("id_image_path"));          // 证件图片路径

        // ====================== 2. 处理联系人及关联楼盘信息 ======================
        // 使用contactId作为键，确保同一联系人仅处理一次（避免多表联查结果中的重复记录）
        Map<Long, CustomerPersonalBasicInfoRequest.ContactInfo> contactMap = new HashMap<>();

        for (Map<String, Object> row : resultList) {
            Long contactId = (Long) row.get("contact_id");
            // 若contactId为空，说明该记录是客户主信息（无联系人关联），跳过
            if (contactId == null) {
                continue;
            }

            // 初始化联系人信息：若contactId不存在于map中，创建新的ContactInfo对象
            CustomerPersonalBasicInfoRequest.ContactInfo contactInfo = contactMap.computeIfAbsent(contactId, k -> {
                CustomerPersonalBasicInfoRequest.ContactInfo ci = new CustomerPersonalBasicInfoRequest.ContactInfo();
                ci.setContactName((String) row.get("contact_name"));        // 联系人姓名
                ci.setContactMobile((String) row.get("contact_mobile"));    // 联系人电话
                ci.setContactEmail((String) row.get("contact_email"));      // 联系人邮箱
                ci.setReceiveProperties(new ArrayList<>());                  // 关联的楼盘名称列表（初始化空列表）
                return ci;
            });

            // 提取楼盘名称（可能来自关联表，允许为空）
            String propertyName = (String) row.get("property_name");
            if (propertyName != null) {
                // 将楼盘名称添加到联系人的关联列表中
                contactInfo.getReceiveProperties().add(propertyName);
            }
        }

        // 将Map中的联系人信息转换为列表，保持插入顺序
        basicInfo.setContactInfos(new ArrayList<>(contactMap.values()));

        return basicInfo;
    }
}